home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / Macintosh Programmer’s Workshop / MPW QR4 / SADE 1.3b1 / SADEScripts / StackCrawl < prev   
Text File  |  1991-04-25  |  2KB  |  102 lines

  1. #    Symbolic Application Debugging Environment    1.2 Beta 2
  2. #
  3. #    Copyright Apple Computer, Inc. 1987-1988
  4. #    All rights reserved.
  5.  
  6. ###############################################################################
  7. func StackOk()
  8.     return ((A7 & 1) = 0)                     ∂
  9.                  && ((BufPtr & 1) = 0)        ∂
  10.                  && (A7 <= BufPtr)
  11. end
  12.  
  13. func ReturnAddress(addr)
  14.     define instr, calladdr
  15.     # check if addr is in an executable region
  16.     callAddr := addr - 2
  17.     instr := ^unsignedword(callAddr)^
  18.     if instr = $6100 then
  19.         return callAddr    # BSR with byte displacement
  20.     elseif (instr & $FFF8) = $4E90 then
  21.         return callAddr    # JSR (An)
  22.     end
  23.     callAddr := addr - 4
  24.     instr := ^unsignedword(callAddr)^
  25.     if instr = $6100 then
  26.         return callAddr    # BSR with word displacement
  27.     elseif (instr & $FFF8) = $4EA8 then
  28.         return callAddr    # JSR (disp, An)
  29.     elseif (instr & $FFF8) = $4EB0 then
  30.         return callAddr    # JSR (disp, An, Dn)
  31.     elseif instr = $4EBA then
  32.         return callAddr    # JSR (disp, PC)
  33.     elseif instr = $4EBB then
  34.         return callAddr    # JSR (disp, PC, Dn)
  35.     elseif instr = $4EB8 then
  36.         return callAddr    # JSR (xxxx).W
  37.     end
  38.     callAddr := addr - 6
  39.     instr := ^unsignedword(callAddr)^
  40.     if instr = $4EB9 then
  41.         return callAddr    # JST (xxxx).L
  42.     end
  43.     return 0        # not a return addr
  44. end
  45.  
  46. func FrameOwner(addr)
  47.     define i, name := where(addr)
  48.     if length(name) = 0 then
  49.         name := '???'
  50.     else
  51.         for i := 1 to length(name) do
  52.             if copy(name, i, 1) = '+' then
  53.                 name := copy(name, 1, i - 1)
  54.                 leave
  55.             end
  56.         end
  57.     end
  58.     name := concat(name, copy('                  ', 1, 18 - length(name)))
  59.     return name
  60. end
  61.  
  62. proc ShowLastFrame(thisPc)
  63.     printf "<main>     %t\n", FrameOwner(thisPc)
  64. end
  65.  
  66. proc ShowFrame(thisA6, thisPC)
  67.     define callAddr, retAddr, nextA6, validFrame, name
  68.     nextA6            := thisA6^
  69.     retAddr            := (thisA6 + 4)^
  70.     validFrame    := ((nextA6 & 1) = 0)    &&        ∂
  71.                                  (nextA6 > thisA6)    &&        ∂
  72.                                  (nextA6 <= (BufPtr - 8))
  73.     printf "%.8X   %t", thisA6, FrameOwner(thisPC)
  74.     if (callAddr := ReturnAddress(retAddr)) <> 0 then
  75.         name := where(callAddr)
  76.         if length(name) = 0 then
  77.             printf "%.8X\n", callAddr
  78.         else
  79.             printf "%t\n", where(callAddr)
  80.         end
  81.     else
  82.         printf "\n"
  83.     end
  84.     if validFrame then
  85.         ShowFrame(nextA6, retAddr)
  86.     else
  87.         ShowLastFrame(retAddr)
  88.     end
  89. end
  90.  
  91. proc StackCrawl
  92.     if not StackOk() then
  93.         printf "Bad Stack\n"
  94.     elseif ((A6 & 1) = 0) && (A6 >= A7) && (A6 <= (BufPtr - 8)) then
  95.         printf "Stack frames using A6 links\n"
  96.         printf "SF Addr    SF Owner          Called From\n"
  97.         ShowFrame(A6, PC)
  98.     else
  99.         printf "A6 stack frame error\n"
  100.     end
  101. end
  102.